/* ------------------------------------------ http请求工具类 ------------------------------------------ */

import axios from "axios";
import globalConfig from "@/assets/global/globalConfig";
import { color as colorLog } from "./log";

// 请求实例
const instance = axios.create({
  timeout: globalConfig.timeout
});
// 日志打印器
const logHandler = {
  // 请求日志打印
  request(config) {
    // 请求数+1
    globalConfig.requestCount++;

    // 打印日志
    colorLog(
      `${config.method} to ${config.reqCode || config.reqPath} [${
        config.reqDesc
      }] =>`,
      "blue"
    );
    if (config.method === "post") {
      console.log(config.data);
    } else if (config.method === "get") {
      console.log(config.params);
    }

    // 开启loading
    if (config.customSet.needLoading) {
      // utils.ui.openLoading({ openColor: globalConfig.ui.colorTheme });
    }
  },
  // 返回成功日志打印
  response(response) {
    // 请求数-1
    globalConfig.requestCount--;

    // 打印日志
    const config = response.config;
    colorLog(
      `${config.method} to ${config.reqCode || config.reqPath} [${
        config.reqDesc
      }] √`,
      "green"
    );
    console.log(response.data);

    // 无正在进行的请求，关闭loading
    if (globalConfig.requestCount === 0) {
      // utils.ui.closeLoading({ closeColor: globalConfig.ui.colorSuccess });
    }
  },
  // 错误日志打印
  error(error) {
    // 请求数-1
    globalConfig.requestCount--;

    // 打印日志
    const config = utils.creator.copy(error).config;
    if (config) {
      // 非纯js报错
      colorLog(
        `${config.method} to ${config.reqCode || config.reqPath} [${
          config.reqDesc
        }] X`,
        "red"
      );
    }
    console.log(error.message);

    // 关闭loading
    // utils.ui.closeLoading({ closeColor: globalConfig.ui.colorError });

    // 如果指定需要错误提示的话，则进行tips错误提示
    if (config.customSet.needErrorTips) {
      // utils.ui.tips({
      //   msg: error.message,
      //   type: "error"
      // });
    }
  }
};

// 根据code设置config
function setConfigByCode(config) {
  // 设置请求头
  config.headers.post["Content-Type"] =
    "application/x-www-form-urlencoded;charset=UTF-8";
  // 转换参数成formData格式(&符号分隔)
  config.transformRequest = [
    function(data) {
      let formData = "";
      // 遍历key拼接formData
      for (const key in data) {
        const value = data[key];
        if (typeof value === "object") {
          // 为对象
          formData +=
            encodeURIComponent(key) +
            "=" +
            encodeURIComponent(JSON.stringify(value)) +
            "&";
        } else {
          // 非对象
          formData +=
            encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
        }
      }
      // 删除末尾&
      if (formData.endsWith("&")) {
        formData = formData.substr(0, formData.length - 1);
      }
      // 返回formData
      return formData;
    }
  ];
  // 拼接真正的请求路径
  config.url = globalConfig.serverUrl + config.reqCode + ".do";
  // 设置data
  config.data = {
    opt: {
      ...config.data, // 主请求数据
    },
    serviceId: config.reqCode, // 接口号
  };
}

// 根据path设置config
function setConfigByPath(config) {
  // 拼接真正的请求路径--不指定请求前缀默认serverUrl
  config.url = config.reqPath.startsWith("http")
    ? config.reqPath
    : globalConfig.serverUrl + config.reqPath;
}

// 请求拦截器
instance.interceptors.request.use(
  config => {
    try {
      // interfaceObj暂存在url字段中
      const interfaceObj = config.url;
      console.log("到底是个啥", config);
      // 塞入interfaceObj字段，以便后续取到
      config.reqCode = interfaceObj.reqCode;
      config.reqPath = interfaceObj.reqPath;
      config.reqDesc = interfaceObj.reqDesc;

      // customSet处理
      // customSet暂存在data请求参数中(post)，或params请求参数中(get)
      if (config.method === "post") {
        // post请求
        // config塞入customSet，以便后续取到
        config.customSet = config.data.customSet;
        // data中删除暂存的customSet属性
        Reflect.deleteProperty(config.data, "customSet");
      } else if (config.method === "get") {
        // get请求
        // config塞入customSet，以便后续取到
        config.customSet = config.params.customSet;
        // params中删除暂存的customSet属性
        Reflect.deleteProperty(config.params, "customSet");
      }

      // 打印日志
      // logHandler.request(config);

      // 处理不同的请求
      if (config.reqCode) {
        // 与后台约定的请求
        setConfigByCode(config);
      } else if (config.reqPath) {
        // 其他请求，带reqPath
        setConfigByPath(config);
      }
    } catch (error) {
      // 发生错误，关闭请求：会进返回拦截器的error分支
      const source = axios.CancelToken.source();
      source.cancel(`请求被取消，原因：${error.message}`);
      config.cancelToken = source.token;
    }

    // 返回处理过后的config
    return config;
  },
  error => {
    // 打印日志
    logHandler.error(error);
    // 返回promise
    return Promise.reject(error.message);
  }
);

// 返回拦截器
instance.interceptors.response.use(
  response => {
    try {
      // 打印日志
      logHandler.response(response);
      // 返回数据
      return response.data;
    } catch (error) {
      error.config = response.config;
      // 打印日志
      logHandler.error(error);
      // 返回reject
      return Promise.reject(error.message);
    }
  },
  error => {
    // 打印日志
    logHandler.error(error);
    // 返回reject
    return Promise.reject(error.message);
  }
);

// 初始化的客制化set
const initCustomSet = {
  needErrorTips: true, // 在发生错误时显示tips
  needLoading: true // 请求时是否显示loading
};

/**
 * get请求
 * @param {*} interfaceObj 接口对象，interfaces文件夹中定义
 * @param {*} params 请求参数
 * @param {*} customSet 客制化set
 */
export const get = (interfaceObj, params = {}, customSet) => {
  customSet = {
    ...initCustomSet,
    ...customSet
  };
  params.customSet = customSet;
  return instance.get(interfaceObj, { params: params });
};

/**
 * post请求
 * @param {*} interfaceObj 接口对象，interfaces文件夹中定义
 * @param {*} params 请求参数
 * @param {*} customSet 客制化set
 */
export const post = (interfaceObj, params = {}, customSet) => {
  customSet = {
    ...initCustomSet,
    ...customSet
  };
  params.customSet = customSet;
  console.log("猜猜看");
  return instance.post(interfaceObj, params);
};

const http = {
  get,
  post
};

export default http;
